using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class ClassEditorMenu : MonoBehaviour {
	
	public UILabel className;
	public UIPopupList hitDie;
	public UIPopupList AttackProgression;
	public UICheckbox fFort;
	public UICheckbox fRef;
	public UICheckbox fWill;
	public UILabel skillsPerLevel;
	public UICheckbox isCaster;
	public UICheckbox isArcane;
	public UIPopupList spellList;
	public UIPopupList castingStat;
	public SpellsPerDayListCreator SpellsPerDay;
	public UICheckbox unlimitedSpells;
	public SpellsPerDayListCreator SpellsKnown;
	public GameObject AddSkillButton;
	public GameObject AddAbilityButton;
	public GameObject CancelButton;
	public GameObject AcceptButton;
	
	public GameObject BrowseSelectSearchWindowPrefab;
	
	List<string> classSkills;
	List<GameObject> skillLabels;
	public GameObject CreateSkillWindowPrefab;
	
	List<GameObject> abilityLabels;
	
	Dictionary<int, List<string>> classAbilities;
	
	public UITable holder;
	
	public GameObject target;
	public string functionName;
	
	string fileName;
	
	static GameReference _reference;
	
	static GameReference reference
	{
		get
		{
			if(_reference == null)
				_reference = GameObject.FindObjectOfType(typeof(GameReference)) as GameReference;
			return _reference;
		}
	}
	
	bool Loaded = false;

	// Use this for initialization
	void Start () {	
		spellList.items = new List<string>();
		spellList.items.AddRange(SpellManager.spellLists.Keys);
	
		UIButtonMessage message = AddSkillButton.AddComponent<UIButtonMessage>();
		message.target = gameObject;
		message.functionName = "AddSkillClicked";
		
		message = AddAbilityButton.AddComponent<UIButtonMessage>();
		message.target = gameObject;
		message.functionName = "AddAbilityClicked";
		
		if(!Loaded)
		{			
			message = CancelButton.AddComponent<UIButtonMessage>();
			message.target = gameObject;
			message.functionName = "CancelButtonClicked";
			
			message = AcceptButton.AddComponent<UIButtonMessage>();
			message.target = gameObject;
			message.functionName = "AcceptButtonClicked";
			
			skillLabels = new List<GameObject>();
			abilityLabels = new List<GameObject>();
			classAbilities = new Dictionary<int, List<string>>();
		}
	}
	
	public void LoadClassDisplay(string cName, bool noEdit = false)
	{
		skillLabels = new List<GameObject>();
		abilityLabels = new List<GameObject>();
		classAbilities = new Dictionary<int, List<string>>();
		classSkills = new List<string>();
		
		CharacterClass c = ClassManager.Load(cName);
		
		fileName = cName;
		
		className.text = c.name;
		hitDie.selection = "d"+c.hitDie;
		AttackProgression.selection = c.BABProgression;
		fFort.isChecked = c.FortFavored;
		fRef.isChecked = c.RefFavored;
		fWill.isChecked = c.WillFavored;
		skillsPerLevel.text = c.skillsPerLevel.ToString();
		isCaster.isChecked = c.MagicUser;
		isArcane.isChecked = c.ArcaneCaster;
		spellList.selection = c.SpellList;
		castingStat.selection = c.SpellcastingAbility;
		SpellsPerDay.spellsTable = c.spellsPerDay;
		SpellsKnown.spellsTable = c.spellsKnown;
		CreateSkillObjects(c.classSkills);
		
		unlimitedSpells.isChecked = (c.spellsKnown == null);
		
		Loaded = true;
		
		foreach(KeyValuePair<int, List<string>> aList in c.abilityTable)
		{
			AbilitySetByLevelLabel aset = AddAbilityGroupLabel(aList.Key);
			aset.UpdateAbilityLists(aList.Value);
			UpdateAbilitySet(aset);
		}
		
		if(noEdit)//!isCustom && Application.platform != RuntimePlatform.WindowsEditor)
		{
			NGUITools.AddWidgetCollider(gameObject);
			
			foreach(Collider l in gameObject.GetComponentsInChildren<Collider>())
			{
				l.enabled = false;
			}
			
			collider.enabled = true;
			
			AddSkillButton.SetActiveRecursively(false);
			AddAbilityButton.SetActiveRecursively(false);
			CancelButton.SetActiveRecursively(false);
			
			UIButtonMessage message = AcceptButton.AddComponent<UIButtonMessage>();		
			message.target = gameObject;
			message.functionName = "CancelButtonClicked";
			message.collider.enabled = true;
		}
		else
		{
			foreach(UIInput l in gameObject.GetComponentsInChildren<UIInput>())
			{
				l.text = l.label.text;
				l.mDefaultText = "Ability Info";
			}
			
			UIButtonMessage message = AcceptButton.AddComponent<UIButtonMessage>();		
			message.target = gameObject;
			message.functionName = "SaveChangesClicked";
			
			CancelButton.GetComponentInChildren<UILabel>().text = "Delete!";
			message = CancelButton.AddComponent<UIButtonMessage>();		
			message.target = gameObject;
			message.functionName = "DeleteClicked";
		}
	}
	
	void AddSkillClicked()
	{
		BrowserManager.CreateSkillBrowser(gameObject, "CreateSkillObjects", classSkills);
	}
	
	/*void AddNewSkill(BrowseEditWindow returnWindow)
	{
		GameObject g = Instantiate(CreateSkillWindowPrefab) as GameObject;
		g.transform.parent = transform.parent;
		g.transform.localScale = Vector3.one;
		g.transform.localPosition = Vector3.back * 300;
		
		CreateSkillWindow skillWindow = g.GetComponent<CreateSkillWindow>();
		skillWindow.target = returnWindow.gameObject;
		skillWindow.functionName = "ReturnMessageNew";
	}
	
	void SkillInfoClick(BrowseEditWindow returnWindow)
	{
		GameObject g = Instantiate(CreateSkillWindowPrefab) as GameObject;
		g.transform.parent = transform.parent;
		g.transform.localScale = Vector3.one;
		g.transform.localPosition = Vector3.back * 300;
		
		CreateSkillWindow skillWindow = g.GetComponent<CreateSkillWindow>();
		skillWindow.target = returnWindow.gameObject;
		skillWindow.functionName = "RemoveInfoTarget";
		skillWindow.LoadSkillDisplay(returnWindow.infoTarget);
	}*/
	
	void CreateSkillObjects(List<string> selections)
	{
		if(selections != null)
			classSkills = selections;
		
		foreach(GameObject skill in skillLabels)
		{
			Destroy(skill);
		}
		
		classSkills.Sort();
		for(int i = 0; i < classSkills.Count; i++)
		{
			GameObject g = Instantiate(reference.SkillLabelPrefab) as GameObject;
			g.name = "k " + (i+2) + " SkillLabel";
			g.transform.parent = AddSkillButton.transform.parent;
			g.active = true;
			g.transform.localScale = Vector3.one;
			g.transform.position = AddSkillButton.transform.position;
			
			g.GetComponentInChildren<UIDragObject>().target = holder.transform;
			
			g.GetComponentInChildren<UILabel>().text = classSkills[i];
			skillLabels.Add(g);
		}
		
		holder.repositionNow = true;
	}
	
	AbilitySetByLevelLabel AddAbilityGroupLabel(int i)
	{	
		if( i >= 1 && i <= 20 && !classAbilities.ContainsKey(i))
		{
			GameObject g = Instantiate(reference.AbilityLabelPrefab) as GameObject;
			
			g.GetComponentInChildren<UIDragObject>().target = holder.transform;
			
			string n = "l ";
			int tempI = i;
			while(tempI+2 > 9)
			{
				n = n+9;
				tempI-=9;
			}
			n = n+(tempI+2);
			
			g.name = n + " AbilityLabel";
			g.transform.parent = AddAbilityButton.transform.parent;
			g.active = true;
			g.transform.localScale = Vector3.one;
			
			g.transform.localPosition = AddAbilityButton.transform.localPosition;//abilityLabelPrefab.transform.position;
			
			AbilitySetByLevelLabel abilitySet = g.GetComponent<AbilitySetByLevelLabel>();
			abilitySet.level.text = "Lvl. " + i;
			abilitySet.target = gameObject;
			abilitySet.functionName = "UpdateAbilitySet";
			abilitySet.levelNum = i;
			
			classAbilities.Add(i, new List<string>());
			
			abilityLabels.Add(g);
			
			return abilitySet;
		}
		
		else
			return null;
	}
	
	IEnumerator AddAbilityClicked()
	{
		List<SetterWindowDescription> setterVars = new List<SetterWindowDescription>
		{
			new SetterWindowDescription("Level", "1", false)
		};
		
		yield return StartCoroutine(HelperFunctions.SetterWindow("Abilities Gained at Level?", setterVars));
		
		int i;
		if(int.TryParse(setterVars[0].outVariable, out i))
		{
			AddAbilityGroupLabel(i);
		}
		
		holder.repositionNow = true;
	}
	
	void UpdateAbilitySet(AbilitySetByLevelLabel abilitySet)
	{
		if(abilitySet != null)
		{
			classAbilities[abilitySet.levelNum] = abilitySet.abilities;
		}
		else
		{
			//classAbilities.Remove(int.Parse(abilitySet.level.text));
			//holder.repositionNow = true;
		}
	}
	
	void SaveChangesClicked()
	{
		if(unlimitedSpells.isChecked)
			SpellsKnown.spellsTable = null;
		
		int i;
		if(!int.TryParse(skillsPerLevel.text, out i))
			i = 0;
		
		CharacterClass c = ClassManager.LoadClassFromData(	className.text, "", int.Parse(hitDie.selection.Remove(0,1)), 
								isCaster.isChecked, isArcane.isChecked, spellList.selection, castingStat.selection,
								fFort.isChecked, fRef.isChecked, fWill.isChecked, AttackProgression.selection, 
								i, classSkills, classAbilities, SpellsPerDay.spellsTable, SpellsKnown.spellsTable);
		
		if(ClassManager.SaveClass(c, fileName))
		{
		target.SendMessage("renamedObject", new KeyValuePair<string, string>(fileName, c.name), SendMessageOptions.DontRequireReceiver);
		
		Destroy(gameObject);
		}
	}
	
	void CancelButtonClicked()
	{
		Destroy(gameObject);
	}
	
	IEnumerator DeleteClicked()
	{
		List<bool> b = new List<bool>{false};
		
		yield return StartCoroutine(HelperFunctions.ConfirmationWindow("Are you sure you want to destroy " + fileName + "?", b));
		
		if(b[0])
		{
			ClassManager.DeleteClass(fileName);
			if(target != null)
				target.SendMessage(functionName);
		}
		
		Destroy(gameObject);
	}
	
	void AcceptButtonClicked()
	{
		if(unlimitedSpells.isChecked)
			SpellsKnown.spellsTable = null;
		
		int i;
		if(!int.TryParse(skillsPerLevel.text, out i))
			i = 0;
		
		Debug.Log("Attempting");
		
		CharacterClass c = ClassManager.AddClass(	className.text, "", int.Parse(hitDie.selection.Remove(0,1)), 
								isCaster.isChecked, isArcane.isChecked, spellList.selection, castingStat.selection,
								fFort.isChecked, fRef.isChecked, fWill.isChecked, AttackProgression.selection, 
								i, classSkills, classAbilities, SpellsPerDay.spellsTable, SpellsKnown.spellsTable);
		
		if(target != null)
			target.SendMessage(functionName, new KeyValuePair<string,string>(c.name, ""), SendMessageOptions.DontRequireReceiver);
	
		Destroy(gameObject);
	}
}
